﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using TJDevHouse.Starcraft.Game;

namespace TJDevHouse.Starcraft.AIModuleConnector.ImportExport
{
	/// <summary>
	/// Handles the creation of a map from the raw data given by the AIModule
	/// </summary>
	class RawMapDataImporter
	{

		//bitmask definitions
		const int BM_BUILDABLE = 4;
		const int BM_WALKABLE = 2;
		const int BM_HIGHGROUND = 1;

		public TJDevHouse.Starcraft.Game.Map CreateMap(string mapData, string mineralData, string gasData, string locationData)
		{
			TJDevHouse.Starcraft.Game.Map theMap;
			try
			{
				string[] map = mapData.Split(":".ToCharArray());
				string data = map[4];

				string mapName = map[0];
				int mapHash = Int32.Parse(map[1]);
				int MapBuildWidth = System.Int32.Parse(map[2]);
				int MapBuildHeight = System.Int32.Parse(map[3]);

				int MapWalkableHeight = MapBuildHeight * 4;
				int MapWalkableWidth = MapBuildWidth * 4;

				theMap = new TJDevHouse.Starcraft.Game.Map(mapHash, mapName, MapBuildWidth, MapBuildHeight);

				int total = MapWalkableWidth * MapWalkableHeight;
				for (int i = 0; i < total; i++)
				{
					int x = i % (MapWalkableWidth);
					int y = i / (MapWalkableWidth);

					int tile = (int)(System.Char.GetNumericValue(data[i]));

					bool height = BM_HIGHGROUND == (tile & BM_HIGHGROUND);
					bool walkable = BM_WALKABLE == (tile & BM_WALKABLE);

					theMap.GetWalkTile(x, y).IsHighGround = height;
					theMap.GetWalkTile(x, y).IsWalkable = walkable;

					//only create a new build tile when needed
					if (x % 4 == 0 && y % 4 == 0)
					{
						bool buildable = BM_BUILDABLE == (tile & BM_BUILDABLE);
						theMap.GetBuildTile(x / 4, y / 4).IsBuildable = buildable;
					}

				}

				//add in the static resources
				foreach (TJDevHouse.Starcraft.Game.BuildTileMapCoordinate coord in ParseStaticMinerals(mineralData))
				{
					theMap.AddStaticMineral(coord);
				}

				//add in the static resources
				foreach (TJDevHouse.Starcraft.Game.BuildTileMapCoordinate coord in ParseStaticGas(gasData))
				{
					theMap.AddStaticGeyser(coord);
				}

				//add in starting locations
				foreach (TJDevHouse.Starcraft.Game.BuildTileMapCoordinate coord in ParseLocationData(locationData))
				{
					theMap.AddStartingLocation(coord);
				}




				return theMap;
			}
			catch (Exception e)
			{
				Console.WriteLine("Error importing map data: " + e.ToString());
				throw;
			}

		}

		/// <summary> Parses the starting locations.</summary>
		/// ///TODO move this to Map data import so can tell the location what map it is on easier
		protected List<TJDevHouse.Starcraft.Game.BuildTileMapCoordinate> ParseLocationData(System.String locationData)
		{
			List<TJDevHouse.Starcraft.Game.BuildTileMapCoordinate> locations = new List<TJDevHouse.Starcraft.Game.BuildTileMapCoordinate>();

			System.String[] locs = locationData.Split(":".ToCharArray());
			bool first = true;

			foreach (String location in locs)
			{
				if (first)
				{
					first = false;
					continue;
				}

				System.String[] coords = location.Split(";".ToCharArray());

				int x = System.Int32.Parse(coords[0]) + 2;
				int y = System.Int32.Parse(coords[1]) + 1;

				TJDevHouse.Starcraft.Game.BuildTileMapCoordinate loc = new TJDevHouse.Starcraft.Game.BuildTileMapCoordinate(x, y);
				locations.Add(loc);
			}

			return locations;
		}

		/// <summary>
		/// Processes the string of mineral/gas positions
		/// </summary>
		/// <param name="mineralData"></param>
		protected List<TJDevHouse.Starcraft.Game.BuildTileMapCoordinate> ParseStaticResourceOfType(UnitType type, String resourceData)
		{
			List<TJDevHouse.Starcraft.Game.BuildTileMapCoordinate> resources = new List<TJDevHouse.Starcraft.Game.BuildTileMapCoordinate>();

			string[] rData = resourceData.Split(":".ToCharArray());

			if (rData.Length == 0)
			{
				return resources;
			}

			for (int i = 1; i < rData.Length; i++)
			{
				string[] thisPos = rData[i].Split(";".ToCharArray());

				int x = int.Parse(thisPos[0]);
				int y = int.Parse(thisPos[1]);

				TJDevHouse.Starcraft.Game.BuildTileMapCoordinate r = new TJDevHouse.Starcraft.Game.BuildTileMapCoordinate(x, y);
				resources.Add(r);
			}

			return resources;

		}

		protected List<TJDevHouse.Starcraft.Game.BuildTileMapCoordinate> ParseStaticMinerals(string mineralData)
		{
			return ParseStaticResourceOfType(UnitType.Resource_Mineral_Field, mineralData);
		}

		protected List<TJDevHouse.Starcraft.Game.BuildTileMapCoordinate> ParseStaticGas(string gasData)
		{
			return ParseStaticResourceOfType(UnitType.Resource_Vespene_Geyser, gasData);
		}
	}
}
